package com.scorpio.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.scorpio.common.exception.CustomException;
import com.scorpio.common.service.impl.BaseServiceImpl;
import com.scorpio.common.utils.ConvertUtils;
import com.scorpio.common.utils.StringUtils;
import com.scorpio.common.utils.ip.AddressUtils;
import com.scorpio.common.utils.treenode.TreeNodeUtil;
import com.scorpio.redis.RedisCache;
import com.scorpio.redis.cachelock.RedisLock;
import com.scorpio.redis.constant.RedisConstants;
import com.scorpio.system.domain.SysAreaInfoEntity;
import com.scorpio.system.dto.SysAreaInfoTreenode;
import com.scorpio.system.mapper.SysAreaInfoMapper;
import com.scorpio.system.service.SysAreaInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Collection;
import java.util.List;

/**
 * 城市Service业务层处理
 *
 * @author scorpio
 * @date 2020-10-10
 */
@Service
public class SysAreaInfoServiceImpl extends BaseServiceImpl<SysAreaInfoMapper, SysAreaInfoEntity> implements SysAreaInfoService {

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private RedisLock redisLock;

    @Override
    public SysAreaInfoEntity selectById(Long id) {
        return baseDao.selectById(id);
    }

    @Override
    public SysAreaInfoEntity selectByCode(String areaCode) {
        return baseDao.selectByCode(areaCode);
    }

    @Override
    public SysAreaInfoEntity selectByName(String name) {
        return baseDao.selectByName(name);
    }

    @Override
    public SysAreaInfoEntity selectByAbbName(String abbName) {
        return baseDao.selectByAbbName(abbName);
    }

    @Override
    public List<SysAreaInfoEntity> selectByCodes(String areaCodes) {
        return baseDao.selectByCodes(areaCodes);
    }

    @Override
    public List<SysAreaInfoEntity> selectByLevel(Long level) {
        return baseDao.selectByLevel(level);
    }

    @Override
    public List<SysAreaInfoEntity> selectByPid(Long pid) {
        return baseDao.selectByPid(pid);
    }

    @Override
    public List<SysAreaInfoTreenode> tree(Long level) {
        List<SysAreaInfoTreenode> tree = redisCache.getCacheObject(getCacheKey(level));
        if (tree == null) {
            String key = "SysAreaInfoTreenode";
            if (redisLock.lock(key, 5)) {
                tree = redisCache.getCacheObject(getCacheKey(level));
                if (tree == null) {
                    QueryWrapper<SysAreaInfoEntity> queryWrapper = getQueryWrapper();
                    if (level != null) {
                        queryWrapper.le("area_level", level);
                    }
                    queryWrapper.orderByAsc("area_code");
                    List<SysAreaInfoEntity> list = baseDao.selectList(queryWrapper);
                    tree = TreeNodeUtil.bulid(ConvertUtils.sourceToTarget(list, SysAreaInfoTreenode.class), 0l, level.intValue());
                    redisCache.setCacheObject(getCacheKey(level), tree);
                }
            } else {
                throw new CustomException("请稍后再试");
            }
        }
        return tree;
    }

    @Override
    public void clearCache() {
        Collection<String> keys = redisCache.keys(RedisConstants.SYS_AREA_CACHE + "*");
        redisCache.deleteObject(keys);
    }

    private String getCacheKey(Long level) {
        return RedisConstants.SYS_AREA_CACHE + (level == null ? "ALL" : "" + level);
    }
}
